//
//  Stage.swift
//  Z048
//
//  Created by remy on 2020/2/1.
//  Copyright © 2020 remy. All rights reserved.
//

class Stage: SKScene {
    private(set) var isGameOver: Bool = false
    private let blockStage = SKShapeNode(rectOf: Constants.stageSize, cornerRadius: 8.0)
    private var idleIndexes: [Int] = []
//    private var lastCreateIndex: Int = 0
    private var blocks: [Block?] = Array(repeating: nil, count: Constants.count)
    
    override func didMove(to view: SKView) {
        // 初始化块区域
        blockStage.position = UIScreen.center
        blockStage.strokeColor = .clear
        blockStage.fillColor = .clear
        self.addChild(blockStage)
        // 初始化块背景,空闲块索引
        idleIndexes = []
        (0..<Constants.count).forEach {
            let blockBG = SKShapeNode(rectOf: Constants.blockSize, cornerRadius: 6.0)
            blockBG.position = Constants.points[$0]
            blockBG.strokeColor = .clear
            blockBG.fillColor = UIColor(0x000000, 0.1)
            blockStage.addChild(blockBG)
            idleIndexes.append($0)
        }
        // 块区域手势
        _ = view.rx.swipeGesture([.left, .right, .up, .down])
            .when(.recognized)
            .takeUntil(self.rx.deallocated)
            .subscribe(onNext: { [weak self] in
                self?.blockSwipe($0)
            })
//        _ = view.rx.panGesture()
//            .when(.began, .changed, .ended)
//            .takeUntil(self.rx.deallocated)
//            .subscribe({ [weak self] in
//                self?.blockSwipe($0)
//            })
        // 新建块
        blockCreate(2)
    }
    
    private func blockSwipe(_ swipe: UISwipeGestureRecognizer) {
        // blockStage区域内
        guard let view = self.view, blockStage.frame.contains(swipe.location(in: view)) else { return }
        // 没有正在执行的动作且游戏没有结束时继续
        guard !self.hasActions() && !isGameOver else { return }
        let direction = swipe.direction
        // count:横向纵向遍历数,step:横向纵向遍历步进值,baseIndex:遍历起点
        var count: (Int, Int) = (Constants.xCount, Constants.yCount)
        var step: (Int, Int) = (1, Constants.xCount)
        var baseIndex: Int = 0
        if direction == .left || direction == .right {
            count = (count.1, count.0)
            step = (step.1, step.0)
        }
        if direction == .up || direction == .right {
            step = (-step.0, -step.1)
            baseIndex = Constants.count - 1
        }
        var isChanged: Bool = false
        for i in 0..<count.0 {
            let endIndex = baseIndex + step.0 * i
            let arr: [PlainBlock] = (0..<count.1).compactMap {
                return blocks[endIndex + step.1 * $0] as? PlainBlock
            }
            var lastBlock: PlainBlock?
            var canMix: Bool = true
            for block in arr {
                var index: (Int, Int) = (block.index, endIndex)
                blocks[index.0] = nil
                if let lastBlock = lastBlock {
                    if block.level == lastBlock.level, canMix {
                        lastBlock.levelUp()
                        index.1 = lastBlock.index
                        canMix = false
                    } else {
                        index.1 = lastBlock.index + step.1
                        canMix = true
                    }
                } else {
                    canMix = true
                }
                if canMix {
                    block.moveTo(index.1)
                    blocks[index.1] = block
                } else {
                    block.mixTo(index.1)
                }
                if index.0 != index.1 {
                    isChanged = true
                }
                lastBlock = block
            }
        }
        guard isChanged else { return }
        // 初始化空闲块索引
        idleIndexes = (0..<Constants.count).compactMap {
            return blocks[$0] == nil ? $0 : nil
        }
        // 新建块
        blockCreate()
    }
    
    private func blockCreate(_ count: Int = 1) {
        for _ in 0..<count {
            guard idleIndexes.count > 0 else {
                gameOverCheck()
                return
            }
            let i = Int(arc4random()) % idleIndexes.count
            let index = idleIndexes[i]
//            lastCreateIndex = idleIndexes[i]
            idleIndexes.remove(at: i)
            let block = PlainBlock(index: index)
            block.addTo(blockStage)
            blocks[index] = block
        }
        nextState()
    }
    
    private func nextState() {
        
    }
    
    private func gameOverCheck() {
        
    }
    
    func gameSave() {
    
    }
    
    func gameReset() {
        
    }
}
